package com.iot08.admin.controller;

import com.iot08.admin.controller.base.BaseController;
import com.iot08.admin.service.MenuService;
import com.iot08.admin.service.UserService;
import com.iot08.admin.tools.DESEncryptTools;
import com.iot08.admin.utils.SecCodeUtil;
import com.iot08.common.constant.Const;
import com.iot08.common.entity.admin.SysMenu;
import com.iot08.common.entity.admin.SysUser;
import com.iot08.common.response.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @version 1.0
 * @author:rock
 * @time:2020年8月8日 下午2:12:23
 */
@Slf4j
@Controller
@RequestMapping
public class LoginController extends BaseController {

    @Resource
    private UserService userService;
    @Resource
    private MenuService menuService;
    @Value("${sysfile.domain: }")
    private String sysfileDomain;


    /**
     * 登录页
     *
     * @return
     * @throws Exception
     * @author:rock
     * @time:2020年8月8日 下午2:34:40
     */
    @RequestMapping(value = {"", "login"})
    public ModelAndView login() throws Exception {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("admin/login");
        return mv;
    }

    /**
     * 请求登录
     *
     * @return
     * @throws Exception
     * @author:rock
     * @time:2020年8月8日 下午2:34:56
     */
    @ResponseBody
    @RequestMapping(value = "doLogin", method = RequestMethod.POST)
    public Response<Object> doLogin(String account, String password) {
        if (StringUtils.isNotEmpty(account) && StringUtils.isNotEmpty(password)) {
            //shiro管理的session
            Subject currentUser = SecurityUtils.getSubject();
            Session session = currentUser.getSession();
            SysUser user = userService.findUserByAccountAndPassword(account, DESEncryptTools.encode(password));
            if (user != null) {
                //判断账号是否已禁用
                if (!Const.INT_1.equals(user.getStatus())) {
                    //更新登录时间和ip
                    userService.updateLastLoginTime(user.getId(), user.getLastLoginTime(), this.getRemortIP());
                    //设置登录用户信息session
                    session.setAttribute(Const.SESSION_USER, user);
                    session.setTimeout(12 * 60 * 60 * 1000L);
                    if (user.getRole() != null) {
                        //处理所拥有的按钮菜单
                        Map<String, Set<String>> butMap = menuService.handleBut(user.getRole().getMenuIds());
                        session.setAttribute(Const.SESSION_USER_BUT, butMap);
                    }
                    //删除验证码session
                    //session.removeAttribute(Const.SESSION_SECURITY_CODE);
                    //shiro加入身份验证
                    Subject subject = SecurityUtils.getSubject();
                    UsernamePasswordToken token = new UsernamePasswordToken(account, password);
                    try {
                        subject.login(token);
                    } catch (AuthenticationException e) {
                        return Response.failedResponse("身份验证失败！");
                    }
                } else {
                    return Response.failedResponse("抱歉，此账号已被禁用");
                }
            } else {
                return Response.failedResponse("用户名或密码输入错误");
            }
        } else {
            return Response.failedResponse("参数异常");
        }
        return Response.successResponse();
    }

    /**
     * 访问系统首页
     */
    @RequestMapping(value = "/main/{changeMenu}")
    public ModelAndView login_index(@PathVariable("changeMenu") String changeMenu) {
        ModelAndView mv = new ModelAndView();
        SysUser user = getSessionUser();
        if (user != null) {
            mv.setViewName("admin/index");
            mv.addObject("user", user);
            if (user.getRole() != null) {
                List<SysMenu> menus = menuService.listByIds(user.getRole().getMenuIds());
                mv.addObject("menuList", menus);
            }
            mv.addObject("sysfileDomain", sysfileDomain);
        } else {
            mv.setViewName("admin/login");
        }
        return mv;
    }

    /**
     * 进入tab标签
     *
     * @return
     */
    @RequestMapping(value = "/tab")
    public String tab() {
        return "admin/tab";
    }

    /**
     * 进入首页后的默认页面
     *
     * @return
     */
    @RequestMapping(value = "/login_default")
    public String defaultPage() {
        return "admin/default";
    }

    /**
     * 生成验证码
     *
     * @param response
     * @author:rock
     * @time:2020年8月10日 下午2:38:42
     */
    @RequestMapping("code")
    public void generate(HttpServletResponse response) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        String code = SecCodeUtil.drawImg(output);
        log.info("code = {}", code);
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        session.setAttribute(Const.SESSION_SECURITY_CODE, code);
        try {
            ServletOutputStream out = response.getOutputStream();
            output.writeTo(out);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @Description: 退出登录
     * @time: 2020/8/18 10:56
     * @author: Rock
     * @version 1.0
     */
    @RequestMapping("/logout")
    public ModelAndView logout() {
        ModelAndView mv = new ModelAndView();
        this.delSessionUser();
        mv.setViewName("admin/login");
        return mv;
    }

    public static void main(String[] args){

        System.out.println("加密数据 = " + DigestUtils.md5Hex("pinxuan2024"));

    }

}
